
/*
  Touch
  write 2010
  by Alessio Gerace <http://www.gegengineering.it>
  modified  2011
  per:  Lisa onlus 
  
  Sistema per riconoscimento movimento piccoli arti per persone diversamente abili, nello specifico persone in stato di post coma o loked in syndrom
   gestione di un sensore di forza in pin 0 il quale invia un byte al pc quando viene rilevata la pressione e il rilascio

 */

// constants won't change. They're used here to 
// set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int button2Pin = 1; 
const int ledPin =  13;      // the number of the LED pin

const int timePausa=97; //"a" setup tempo pausa def attesaPausa n*90ms
const int setupdata=109; //"m"   tempo accettazione dato def attesaSegnale n*90ms
const int stTouchTime=105; //"i"  tempo di pressione e rilascio sf def minvalTouchPress n*1ms
const int stTouchMTime=112; //"p"  tempo pressione sf prima di richiedere il menu def valTouchtoMenu n*1ms
const int stTouchMinF=115; //"s"  min valore sf def minvalTouch int 

int sensibP=30;   // questo è il ritardo per il controllo dello stato attivo del sensore       
int sensibAP=40;   // questo è il ritardo per il controllo dello stato attivo del sensore Analogico    
int nopulse=120;    // questo controllo serve per la proporzionalità se non viene registrato un segnale dal sensore per 40 cicli
                  // allora attesaSegnale viene aumentato di 100ms  
int minvalTouch=20; //valore minimo sensore di forza se maggiore sensore premuto minore sensore rilasciato
int minvalTouchPress=80; //valore minimo di pressione su sensore di forza 80ms
int valTouchtoMenu=5000;//se viene premuto per 800ms tempo modificabile viene inizializzato il menu
int attesaSegnale=20; //attesa del segnale dal sensore im ms   20*90ms =900 ms 1,8 S   
                     // attesaSegnale formato m1000-> imposta 1000ms -> 1 sec
int attesaPausa=100; //attesa del segnale dal sensore im ms prima di mettere in pausa   20*90ms =1800 ms 1,8 S   
                     // attesaSegnale formato m1000-> imposta 1000ms -> 1 sec
                     
int maxnopulse=120;    // questo controllo serve per la proporzionalità se non viene registrato un segnale dal sensore per 40 cicli
              // allora attesaSegnale viene aumentato di 100ms    
int noS,noS1;
byte nodata=1;        // flag per loop contrrollo 
                  
int sensib=1;     // fattore di moltiplicazione in ms per attesa 



int valorePuls = 0;  // mi dice per quanti centesimi di secondo è rimasto attivo il sensore
int valoreNodata = 0;  // contatore del loop attesa senale
int offset=0; //tempo in cui attende il segnale del sensore IR prima di ritornare al controllo del segnale del sens vibrazione

int incomingByte = 0; // byte acquisito
int maxBuff; //lunghezza buffer in lettura

int buttonState = 0;         // variable for reading the pushbutton status
int Cond = 0;         // variable for reading the pushbutton status
int PauseRun=1; //questo valore indica se il sistema è in pausa =0 o in run =1
int analogValue=0; // variabile che contiene il valore letto dal sensore di forza
int SensorRet=LOW; // Variabile che mi dice che è stata raggiunta almeno una soluzione dal sensore IR
int TouchState=LOW;
//-------------------------SETUP ROGRAM---------------------------
void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);      
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);     
  Serial.begin(115200); 
  analogReference(INTERNAL);
  attachInterrupt(0, Sensor, LOW);

  establishContact(); 
  PauseRun=HIGH;
}
  void establishContact() {
      while (Serial.available() <= 0) 
      {
        Serial.println('D');   // send a capital D
        delay(100);
      }
      Serial.flush();
      digitalWrite(ledPin, LOW); 
      nopulse=0;
  }
  //-------------------------MAIN LOOP-------------------------------
void loop(){
  // read the state of the pushbutton value:
//inizio ciclo di scansione sensore
// controllo dei byte ricevuti 

    LeggiDataSet();

    valorePuls=0;
    offset=0;
    if (PauseRun==HIGH)
     {
         TouchState=Senstouch();
       // TouchState=LOW;
      }
      
}
//-------------------------------END MAIN--------------------------------
//-------------------------------RTX DATA SETUP --------------------------------
void LeggiDataSet()
{
      if (Serial.available() > 0) 
        {
         incomingByte=Serial.read();
         delay(10);
        // Serial.println(Serial.available());
          //maxBuff=Serial.available();
          maxBuff=Serial.available();
          // se trovo la m entro nelle impostazioni 
          if (incomingByte==setupdata)//"m" setup tempo accetta dato
          {
           attesaSegnale=SetData(); 
           Serial.print("s");
           Serial.print(attesaSegnale);      
          }
         if (incomingByte==timePausa)//"a" setup Tempo Pausa 
          {
           attesaPausa=SetData(); 
           Serial.print("s");
           Serial.print(attesaPausa); 
          }
          if (incomingByte==stTouchTime)//"i" valore minimo di pressione rilascio su sens touch
          {
            minvalTouchPress=SetData();
             Serial.print("s");
           Serial.print(minvalTouchPress); 
          }
          if (incomingByte==stTouchMTime)//"p" tempo pressione sf prima di richiedere il menu def valTouchtoMenu n*1ms
          {
            valTouchtoMenu=SetData();
             Serial.print("s");
           Serial.print(valTouchtoMenu); 
          }
          if (incomingByte==stTouchMinF)//"s" min valore sf def minvalTouch int 
          {
            minvalTouch=SetData();
             Serial.print("s");
           Serial.print(minvalTouch); 
          }
             Serial.flush();
             incomingByte=0;
        }
}
//------------------------------------------------------------------
//----------------------DECODE BUFFER-----------------------------------------
int SetData()
{
char  buffer[maxBuff];
int conta=0;
int RetData;
RetData=0;
  for(conta=0;conta<=maxBuff;conta++)
  {
       buffer[conta]=Serial.read();
   }
RetData=atoi(buffer); // converto una stringa di char in integer

return RetData;
};
//------------------------------------------------------------------
//------------------------------------------------------------------
// sub per la gestione del sensore di vibrazione e del calcolo tempi

int Senstouch() 
{
 int RetVal=0; 
 int valbtA=0;
 int contaRel=0;
 int contaTouch=0;
 int Tstep=LOW; // step presssione 
 int Rstep=LOW; // step rilascio
 int Mnu=LOW; // mnu ctrl
 TouchState=LOW;
 Tstep=LOW; // step presssione 
 Rstep=LOW; // step rilascio
 valbtA=LOW;
 RetVal=LOW;
 Mnu=LOW;
 do{
     analogValue = analogRead(button2Pin);
           if(analogValue > minvalTouch) // analog value da settare.
           {
             contaRel=0;
             if (contaTouch>minvalTouchPress)
               {
                Tstep=HIGH;
                //Serial.println("press Ok"); //debug
                }
              if (contaTouch > valTouchtoMenu)
                {
                  contaRel=0;
                  contaTouch=0;
                  Mnu=HIGH;
                }  
             contaTouch+=1;
             delay(1);
           }
           else
           {
             contaTouch=0;
           }
           
       if (Tstep==HIGH && Rstep==LOW )
       {
         
         if(analogValue < minvalTouch) // analog value da settare.
           {
             contaTouch=0;
             if (contaRel>=minvalTouchPress)
                {
              
                  contaTouch=0;
                  contaRel=0;
                  Rstep=HIGH;
                  //Serial.println("relise ok"); //debug
                  //Serial.println(Tstep); //debug
                  //Serial.println(Rstep); //debug
                }      
             contaRel+=1;
           }
            else
           {
             contaRel=0;
           }
         delay(1);
       }
     if (Rstep==HIGH && Tstep==HIGH)
       { 
         valbtA=HIGH; 
         RetVal=HIGH;  
        // Serial.println("exit sub"); //debug
       }
     LeggiDataSet();
   }while (valbtA==LOW);
   
   if (PauseRun==HIGH && Mnu==LOW && RetVal==HIGH)  Serial.print("t"); 
   if (PauseRun==HIGH && Mnu==HIGH && RetVal==HIGH)  Serial.print("m"); 
   return RetVal;
}

//------------------------------------------------------------------
// sub per la gestione del sensore e del calcolo tempi
void Sensor()
{
SensorRet=LOW;
int r,res;
  if (digitalRead(buttonPin)==LOW)
  {
    valorePuls=Pulse();		// say what you got:  
      if (valorePuls>1) 
        {
          nopulse=0;
         // Serial.println(valorePuls);
          if(valorePuls >= attesaSegnale) //(valorePuls >= attesaSegnale && valorePuls < attesaPausa)
            {
              if (PauseRun==HIGH)  Serial.print("d"); //accetta il dato 
              noS=0;
              noS1=0;
              valorePuls=0;
              SensorRet=HIGH;
            }
            if (valorePuls >= attesaPausa)
            {
             /* if (PauseRun==HIGH)
              {
                Serial.print("p"); // mette in pausa
                PauseRun=LOW;
                SensorRet=HIGH;
              }
               else
              {
                Serial.print("i"); // riattivo il sistema
                PauseRun=HIGH;
                SensorRet=HIGH;
                }*/
              noS=0;
              noS1=0;
              valorePuls=0;
          }
        }
        else
        {
            valorePuls=0;    
        }
  }

if (valorePuls==0 && SensorRet==LOW ) 
  {
    if (NoSignal()==1) nopulse+=1;
    if (nopulse>=maxnopulse)
    {
      nopulse=0;
      if (PauseRun==HIGH)  Serial.print("r"); //attesa Segnale
      SensorRet=LOW;
    }
  }
 // return SensorRet;
};
//------------------------------------------------------------------
int NoSignal()
{
int ns_ret=0;
 ns_ret=0;
  noS+=1;
  if (noS>=40)
    {
      noS=0;
      noS1+=1;
      if (noS1>=100)
        {
          noS=0;
          noS1=0;
          ns_ret=1;
        }  
    }
    return ns_ret;
};
//------------------------------------------------------------------
int Pulse()
{
      int a=0;
      a=0;
      nodata=1;
      buttonState = HIGH;
      do{
          digitalWrite(ledPin, HIGH); 
          buttonState = ckPulse();
              a+=1;
              if (a>2)
              {
                 if (a>=attesaSegnale && a < attesaPausa) // es attesaSegnale=20 * 90 ms(ckPulse) + 10 ms (seq) = 1810 ms=> 1,8 S
                {
                  if (PauseRun==HIGH) Serial.print("y"); //colora di verde e seleziona il dato
                }
                if (a >= attesaPausa)
                {
                  Serial.print("x"); // colora di blu e seleziona pausa run
                }
              }
              else
              {
                if (PauseRun==HIGH) Serial.print("h"); // mi manda un dato di segnale letto
              }
          nodata=0;            
        }while (buttonState==HIGH);

      digitalWrite(ledPin, LOW); 
      if (PauseRun==HIGH) Serial.print("l"); //mi dice che è stato perso il segnale riflesso
      return a;

 
};
//------------------------------------------------------------------
int ckPulse() // 90 ms legge in onda di 90ms 
{
    int contack=0;
    int valck=30;
    int ondack;
    int valret=0;
    contack=0;
    valck=30;
    ondack;
    valret=0;
    do{
       if(digitalRead(buttonPin)==LOW) 
       {
       valret+=1;
       }
      // Serial.println(valret);
      contack+=1;
      delay(3);
     
      }while (contack< valck);
      
      if (valret >= 10) //se legge almeno 10/30 bit attivi prende il segnale per buono
      {
        return HIGH;
      }
      else
      {
        return LOW;
      }
}
//------------------------------------------------------------------
